<?php

namespace app\backend\service;

use app\common\model\MemberBindModel;
use app\common\RootService;
use app\common\model\MemberModel;
use app\common\model\SpreadModel;
use app\backend\validate\SpreadValidate;

class SpreadService extends RootService
{
    /**
     * 标签映射
     * @return array
     */
    public function labelData()
    {
        return ['typeLabel' => SpreadModel::$typeLabel, 'sortLabel' => SpreadModel::$sortLabel, 'userLabel' => SpreadModel::$userLabel,
            'platformLabel' => SpreadModel::$platformLabel, 'adminList' => AdminService::adminNames(0, true),
            'bindType' => MemberModel::$bindType];
    }

    /**
     * 推广列表
     * @param array $params
     * @return array
     * @throws \think\db\exception\DbException
     */
    public function lists(array $params)
    {
        // 数据源
        $spreadList = $this->page($this->spreadModel($params)->order(['sp.id' => 'desc']));
        // 数据处理
        $spreadList['data'] = $this->dataFormat($spreadList['data']);
        return $spreadList;
    }

    /**
     * 添加KOL推广
     * @param array $params
     * @return array
     * @throws \app\common\RootException
     */
    public function add(array $params)
    {
        // 参数校验
        $this->verify($params, 'add');
        // 数据处理
        $addData = ['admin_id' => adminInfo('id'), 'remark' => $params['remark'], 'type' => $params['type'],
            'member_id' => $this->getMemberId($params['nickname'], $params['invite']), 'price' => $params['price'],
            'platform' => $params['platform']];
        // 添加失败
        SpreadModel::create($addData) || $this->errorException('添加失败');
        // 添加成功
        return ['msg' => '添加成功', 'preload' => true];

    }

    /**
     * 修改KOL推广
     * @param array $params
     * @return array
     * @throws \app\common\RootException
     */
    public function edit(array $params)
    {
        // 参数校验
        $this->verify($params, 'edit');
        // 数据处理
        $renewData = ['remark' => $params['remark'], 'type' => $params['type'], 'price' => $params['price'],
            'platform' => $params['platform'], 'id' => $params['id']];
        // 修改失败
        SpreadModel::update($renewData) || $this->errorException('修改失败');
        // 修改成功
        return ['msg' => '修改成功', 'preload' => true];
    }

    /**
     * 推广详情
     * @param array $params
     */
    public function info(int $spreadId)
    {
        // 筛选字段
        return $this->spreadModel(['id' => $spreadId])->find()->toArray();
    }

    /**
     * 数据处理
     * @param array $dataList
     * @return array
     */
    protected function dataFormat(array $dataList)
    {
        $labelData = $this->labelData();
        $adminNames = AdminService::adminNames();
        // 数据处理
        array_walk($dataList, function (&$row) use ($adminNames, $labelData) {
            empty($row['remark']) && $row['remark'] = '--';
            $row['typeLabel'] = $labelData['typeLabel'][$row['type']];
            $row['inviteUrl'] = config('rule.inviteUrl') . $row['invite'];
            $row['adminName'] = $adminNames[$row['admin_id']]['real_name'] ?? '--';
            $row['platformLabel'] = $labelData['platformLabel'][$row['platform']] ?? '--';
            $row['bindType'] = $labelData['bindType'][$row['bind_type']] ?? '';
            empty($row['type']) && $row['avgCost'] = $row['effect'] ? $row['price'] / $row['effect'] : $row['price'];
        });
        return $dataList;
    }

    /**
     * 获取用户ID
     * @param string $nickname
     * @param string $invite
     * @return mixed
     * @throws \app\common\RootException
     */
    protected function getMemberId(string $nickname, string $invite = '')
    {
        if (empty($invite)) {
            $memberModel = new MemberModel();
            $invite = generateInvite();
            $avatar = 'static/images/avatar.jpg';
            // 数据处理
            $memberData = ['invite' => $invite, 'nickname' => $nickname, 'device_id' => md5($invite), 'type' => 1,
                'avatar' => $avatar, 'version' => '1.0.0', 'remark' => 'KOL账号', 'ip' => request()->ip(),
                'account' => $invite, 'device_sn' => 'windows'];
            // 新增操作
            try {
                $memberModel->startTrans();
                $memberInfo = $memberModel->create($memberData);// 用户数据
                // 绑定操作
                MemberBindModel::create(['account' => $invite, 'register' => 1, 'member_id' => $memberInfo['id'],
                    'nickname' => $nickname, 'type' => 1, 'avatar' => $avatar]);
                $memberModel->commit();
                // 添加成功
                return $memberInfo['id'];
            } catch (\Exception $e) {
                $memberModel->rollback();
                $this->errorException('添加失败' . $e->getMessage());
            }
        }
        // 更新用户类型为KOL账号
        $memberInfo = MemberModel::where(['invite' => $invite])->find();
        $memberInfo->type = 1;
        $memberInfo->save();
        return $memberInfo['id'];
    }

    /**
     * 校验
     * @param array $params
     * @param string $scene
     * @throws \app\common\RootException
     */
    protected function verify(array $params, string $scene)
    {
        $this->validate(new SpreadValidate(), $scene, $params);
        // 渠道ID校验
        empty($params['userType']) && empty($params['invite']) && $this->errorException('请输入渠道ID');
        // 价格校验
        empty($params['type']) && empty($params['price']) && $this->errorException('付费方式按量付费时推广价格必须大于0');
    }

    /**
     * 推广模型
     * @param array $params
     * @return mixed
     */
    protected function spreadModel(array $params)
    {
        // 推广ID筛选
        empty($params['id']) || $where[] = ['sp.id', '=', $params['id']];
        // 添加人
        empty($params['adminId']) || $where[] = ['sp.admin_id', 'in', $params['adminId']];
        // 筛选字段
        $fields = ['sp.id sid', 'm.id', 'm.nickname', 'm.invite', 'sp.admin_id', 'sp.price', 'sp.create_time', 'sp.type',
            '(select count(id) from sys_member sm where sm.parent_id = m.id) actual', // 实际邀请
            '(select count(id) from sys_member_invite sm where sm.member_id = m.id and sm.type=1) effect', // 有效邀请
            'm.avatar', 'm.bind_type', 'sp.remark', 'sp.platform', '0 avgCost', 'm.state memberState'];
        // 筛选结果
        return SpreadModel::alias('sp')->join(['sys_member' => 'm'], 'sp.member_id = m.id', 'left')
            ->where($where ?? [])->field($fields);
    }
}